﻿//
// Copyright (c) 2011 HyperCrunch, Inc. http://www.hypercrunch.com 
// Author: Nik Kalyani  http://www.kalyani.com (Twitter: @techbubble)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using DotNetNuke.Entities.Users;
using System.Web;
using System.Text;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Entities.Portals;
using System.Collections;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Services.ClientCapability;

namespace HyperCrunch.Druid
{
    public class UIContext
    {

        private DateTime startTime = DateTime.MinValue;

        public UIContext(HttpContext context)
        {
            this.context = context;
            this.user = UserController.GetCurrentUserInfo();
            this.isSuper = user.IsSuperUser;

            if (PortalSettings.Current != null)
            {
                this.activeTab = PortalSettings.Current.ActiveTab;
                this.isAdmin = this.user.IsInRole(PortalSettings.Current.AdministratorRoleName);
                this.isPageAdmin = (TabPermissionController.CanAddContentToPage() 
                                    || TabPermissionController.CanAddPage()
                                    || TabPermissionController.CanAdminPage() 
                                    || TabPermissionController.CanCopyPage()
                                    || TabPermissionController.CanDeletePage() 
                                    || TabPermissionController.CanExportPage()
                                    || TabPermissionController.CanImportPage() 
                                    || TabPermissionController.CanManagePage());
            }

            this.startTime = DateTime.Now;
            this.StylesheetUrls = new RuleStylesheetUrls();
            this.ScriptUrls = new RuleScriptUrls();
            this.JsonSettings = new RuleSettings();
            this.ContentModifiers = new RuleContentModifiers();
            this.Log("User Agent: " + UserAgent);
        }

        private IClientCapability clientCapabilities = null;
        public IClientCapability ClientCapabilities 
        {
            get
            {

                if (clientCapabilities == null)
                {
                    clientCapabilities = (IClientCapability) ClientCapabilityProvider.Instance().GetClientCapability(UserAgent);
                }

                return clientCapabilities;
            }
        }

        public DotNetNuke.Entities.Portals.PortalSettings PortalSettings
        {
            get
            {
                return DotNetNuke.Entities.Portals.PortalSettings.Current;
            }
        }

        private RuleAction action = new RuleAction();
        public RuleAction Action
        {
            get
            {
                return action;
            }
        }


        private TabInfo activeTab = null;
        public TabInfo ActiveTab
        {
            get
            {
                return activeTab;
            }
        }

        private bool isSuper = false;
        public bool IsSuper 
        { 
            get
            {
                return isSuper; 
            }
        }

        private bool isAdmin = false;
        public bool IsAdmin 
        { 
            get
            {
                return isAdmin;
            }
        }

        private bool isPageAdmin = false;
        public bool IsPageAdmin
        {
            get
            {
                return isPageAdmin;
            }
        }

        private UserInfo user = null;
        public UserInfo User
        { 
            get
            { 
                return user;
            }
        }

        private HttpContext context = null;
        public HttpContext Context
        {
            get
            {
                return context;
            }
        }

        public RuleContentModifiers ContentModifiers { get; set; }
        public RuleSettings JsonSettings { get; set; }
        public RuleStylesheetUrls StylesheetUrls { get; set; }
        public RuleScriptUrls ScriptUrls { get; set; }

        public string UserAgent
        {
            get
            {
                if (IsSuper && Context.Request.QueryString["useragent"] != null)
                    return Context.Request.QueryString["useragent"].ToString();
                else
                    return Context.Request.UserAgent;
                //  "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/7D11";
                //  "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"); Firefox 4
            }
        }

        public void Log(string s, LogType logType)
        {
            if (Debug)
            {
                string style = "";
                switch (logType)
                {
                    case LogType.Match: style = " class='Druid-match'"; break;
                    case LogType.NoMatch: style = " class='Druid-nomatch'"; break;
                    case LogType.Error: style = " class='Druid-error'"; break;
                }
                logText.Append("<div" + style + ">" + String.Format("{0:hh:mm:ss.fff tt}", DateTime.Now) + ": " + s + "</div>");
            }
        }

        public void Log(string s)
        {
            Log(s, LogType.Info);
        }

        private bool debug = false;
        public bool Debug
        {
            get
            {
                return debug;
            }

            set
            {
                debug = value;
            }
        }

        private StringBuilder logText = new StringBuilder();
        public string LogText
        {
            get
            {
                if (!Debug) return "";

                string style = @"
                            <style>
                                div.Druid { background-color:#000;color:#fff;padding: 10px; margin: 200px 0px 0px 0px;}
                                div.Druid * { text-align:left; font-size:9pt;font-family:Consolas,Arial,Helvetica,Sans-Serif;}
                                div.Druid h2 { color: #11a2f5; margin-bottom: 10px;font-weight:bold;font-size:1.1em;}
                                div.Druid div { padding: 4px; }
                                div.Druid-match { background-color:#59975c; }
                                div.Druid-nomatch { background-color:#fe5e5b; }
                                div.Druid-error { background-color:#ededed; }
                            </style>";

                StringBuilder results = new StringBuilder();
                
                results.Append("<div><b>Actions Based on Rule Enumeration</b></div>");
                results.Append("<div>ContentRenderer = " + Action.ContentRenderer + "</div>");
                results.Append("<div>SkinSrc = " + Action.SkinControl + "</div>");
                results.Append("<div>ContainerSrc = " + Action.ContainerControl + "</div>");
                results.Append("<div>Theme = " + Action.Theme + "</div>");
                results.Append("<div>RedirectUrl = " + Action.RedirectUrl + "</div>");
                results.Append("<div>Content Modifiers: <br /><ul>");
                foreach (string contentModifier in ContentModifiers)
                    results.Append("<li style=\"margin-left:50px\">" + contentModifier + "</li>");
                results.Append("</ul>");
                results.Append("<div>StyleSheetUrls: <br /><ul>");
                foreach(string stylesheetUrl in StylesheetUrls)
                    results.Append("<li style=\"margin-left:50px\">" + stylesheetUrl + "</li>");
                results.Append("</ul>");
                results.Append("<div>ScriptUrls: <br /><ul>");
                foreach (string scriptUrl in ScriptUrls)
                    results.Append("<li style=\"margin-left:50px\">" + scriptUrl + "</li>");
                results.Append("</ul>");
                results.Append("<div>Settings: <br /><ul>");
                foreach (string setting in JsonSettings.Keys)
                    results.Append("<li style=\"margin-left:50px\">" + setting + " = " + JsonSettings[setting].ToString() + "</li>");
                results.Append("</ul>");
                results.Append("<hr />");

                return  style + 
                        "<div class='Druid'><h2>Druid Rule Processing Debug</h2>" +
                        "<div>Total execution time: " + (DateTime.Now - startTime).Milliseconds.ToString() + " milliseconds" + "</div><hr />" +
                        "<h2>Rule Processing Log</h2>" +
                        logText.ToString() +
                        "<hr />" +
                        results.ToString() + 
                        "<h2>Client Capabilities</h2>" +
                        GetBrowserCapabilities((IDictionary)ClientCapabilities.Capabilities) + 
                        "</div>";

            }
        }


        private static string GetBrowserCapabilities(IDictionary caps)
        {
            StringBuilder cap = new StringBuilder();
            foreach (DictionaryEntry key in caps)
                cap.Append("<tr><td>" + key.Key.ToString() + "</td><td>" + (key.Value == null ? string.Empty : key.Value.ToString()) + "</td></tr>");
            return ("<table>" + cap.ToString() + "</table>");
        }
    
    }
}
